按:下筆此刻,JUCE 版本為 6.1,此系列文章皆以此版為準。
這篇說明加入 UI 控制項的其中一個方法。Projucer 建出來的 GUI Application 專案長這樣:

紅框對應到程式碼中的 MainComponent 類別如下。(為了閱讀舒適,程式碼做了些許調整):
class MainComponent : public juce::Component
{
public:
MainComponent()
{
setSize (600, 400);
}
~MainComponent() = default;
void paint (juce::Graphics&) override
{
g.fillAll(getLookAndFeel().findColour(juce::ResizableWindow::backgroundColourId));
g.setFont (juce::Font (16.0f));
g.setColour (juce::Colours::white);
g.drawText ("Hello World!", getLocalBounds(), juce::Justification::centred, true);
}
void resized() override
{
}
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
paint() 負責畫出視窗中間的 "Hello World!",改成文字按鈕會用到 juce::TextButton 類別。步驟如下:
TextButton 物件,命名為 google_button_
MainComponent 建構式中
google_button_ 按鈕的文字設為 "Google!"onClick 設定其行為:以系統預設瀏覽器開啟 "https://www.google.com"TextButton 物件加到 MainComponent 中,並將其屬性設為 Visible。(使用 addAndMakeVisible 函數)MainComponent::resized 函數中,設定 TextButton 的大小。上下左右各內縮了 10px,讓按鈕的樣子更明顯。改動後的程式碼如下:class MainComponent : public juce::Component
{
public:
MainComponent() :
google_button_("Google!")
{
setSize (600, 400);
google_button_.onClick = []()
{
juce::URL google("https://www.google.com");
google.launchInDefaultBrowser();
};
addAndMakeVisible(google_button_);
}
~MainComponent() = default;
void paint (juce::Graphics&) override
{
g.fillAll(getLookAndFeel().findColour(juce::ResizableWindow::backgroundColourId));
}
void resized() override
{
google_button_.setBounds(getLocalBounds().reduced(10, 10));
}
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
修改後的視窗:

滑鼠點擊 Google! 按鈕開啟 Google 首頁:

前篇提到 JUCE UI 架構下,所有控制項皆繼承自 Component 類別,這個基礎類別的行為之一是可以「容納」其他 Component 物件,例如此例中的 google_button_ 物件。
上面的範例中,使用 addAndMakeVisible 函數把 google_button_ 物件加到 MainComponent 中。
可以把 MainComponent 看成容器,內含了另一個 Component 物件(google_button_),google_button_ 物件即為 MainComponent 的 Child Component。
查看 addAndMakeVisible 實作,其實是兩個動作組成:
void Component::addAndMakeVisible (Component& child, int zOrder)
{
child.setVisible (true);
addChildComponent (child, zOrder);
}
上述範例使用了 TextButton 中的 onClick,其型別為 std::function<void()>。這是在 JUCE 採用了 C++11 規格後,讓開發者可以使用 Lambda 來設計按鈕的邏輯。
JUCE 開發時 C++11 還沒發生,許多組件,例如 Smart Pointer 必須手工打造。支援 C++11/14 標準後,JUCE code base 漸漸改用 C++ 標準函式庫的組件,這是好的進展。理由為何,以後再談。